package com.ayg.test.apitest.core;

import com.ayg.test.apitest.constants.CasesState;
import com.ayg.test.apitest.constants.SqlString;
import com.ayg.test.apitest.constants.TradeState;
import com.ayg.test.apitest.dao.PaymentDao;
import com.ayg.test.apitest.entity.PayTestCase;
import com.ayg.test.apitest.utils.StringUtil;
import com.ayg.test.apitest.utils.YamlRead;
import com.esotericsoftware.yamlbeans.YamlException;
import com.esotericsoftware.yamlbeans.YamlReader;
import com.google.gson.Gson;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.testng.Assert;
import org.testng.ITestContext;
import org.testng.Reporter;

import org.testng.annotations.BeforeSuite;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.*;

public class PaymentDbCaseEngine {
    private static final Logger logger = LoggerFactory.getLogger(PaymentDbCaseEngine.class);
    public static final String API_CONFIG = "/api_config.yaml";
    private Gson gson = new Gson();
    private PaymentDao dao = new PaymentDao();
    private String env = "test";//默认为测试环境

    @BeforeSuite
    public void init() throws Exception {
        //读取全局配置文件，初始化数据
        String global = getClass().getResource(API_CONFIG).getPath();
        YamlRead yamlRead = new YamlRead(global);
        Map apiConfig = (Map)yamlRead.getYmal();
        env = (String)apiConfig.get("env");
        logger.info("获取执行环境：{}",env);
    }

    @BeforeTest
    public void readData(ITestContext context) throws YamlException, FileNotFoundException {
       /* String evnFromXml = context.getCurrentXmlTest().getParameter("env");
        if(StringUtil.isNotEmpty(evnFromXml)){
            env = evnFromXml;
        }*/
    }

    @DataProvider(name = "dbCases")
    public Iterator<Object[]> getDbCaseData(ITestContext context)
            throws Exception {
       return new PaymentDbDataProvider(env);
    }

    @Test(dataProvider="dbCases")
    public void dbCasesTest(PayTestCase payTestCase) throws Exception {
        logger.info("执行用例："+payTestCase.getName());
        //1.前一步接口测试失败的用例这里直接做失败处理，并更新用例状态
        if(payTestCase.getStatus()==CasesState.DEAL_FAIL){
            Reporter.log(payTestCase.getApi_msg());
            dao.update(SqlString.UPDATE_TESTCASE_STATUS,CasesState.FAIL,payTestCase.getId());
            Assert.assertTrue(false,payTestCase.getApi_msg());
        }
        //2.根据支付处理结果（数据表状态）来判断用例的执行情况
        String reqResult = payTestCase.getReq_result();
        Map list = null;
        Map result = new HashMap();
        String tradeState = null ;
        String notifyResultCode = null;
        String dealResultMessage ;
        if(payTestCase.getType()==1 || payTestCase.getType()==-1){
            list = dao.query(env,SqlString.PAYMENT_TESTCASE_STATE_SQL,reqResult);
            if(list!=null) {
                 tradeState = (String) list.get("state");
                 notifyResultCode = (String) list.get("notify_resultcode");
                 dealResultMessage = (String) list.get("deal_resultmessage");

                result.put("state", tradeState);
                result.put("notifyResultCode", notifyResultCode);
                result.put("dealResultMessage", dealResultMessage);

            }
        }else if(payTestCase.getType()==2){
            list = dao.query(env,SqlString.ADJUST_TESTCASE_STATE_SQL,reqResult);
            if(list!=null){
                 tradeState = (String) list.get("adjust_state");
                 notifyResultCode = (String) list.get("notify_resultcode");
                 dealResultMessage = (String) list.get("adjust_resultmessage");
                result.put("state",tradeState);
                result.put("notifyResultCode",notifyResultCode);
                result.put("dealResultMessage",dealResultMessage);
            }
        }
        Reporter.log(payTestCase.getRequest());
        Reporter.log(payTestCase.getValidate());
        Reporter.log(payTestCase.getReq_result());

        boolean isSuccess = false;
        int caseState = CasesState.DEAL_SUCCESS;
        if(TradeState.PROCESSING.equals(tradeState) || TradeState.SUSPEND.equals(tradeState)){
            //交易处理中
            caseState = CasesState.TRADE_PROCESSING;//
        }else if(TradeState.SUCCESS.equals(tradeState)){
            //交易处理成功并通知业务方成功，case状态更新为成功，其余均为失败
            if(TradeState.SUCCESS.equals(notifyResultCode)){
                caseState = CasesState.SUCCESS;
                isSuccess = true;
            }else{
                //支付会重试notify
                caseState = CasesState.FAIL;
            }
        }else if(TradeState.FAIL.equals(tradeState)) {
            //判断是用例的正常路径还是异常路径
            if(payTestCase.getType()<0){
                caseState = CasesState.SUCCESS;
                isSuccess = true;
            }else {
                caseState = CasesState.FAIL;
            }
        }
        //更新用例状态
        dao.update(SqlString.UPDATE_TESTCASE_STATUS,caseState,payTestCase.getId());
        String jsonResult = gson.toJson(result);
        logger.info(jsonResult);
        Reporter.log(jsonResult);
        Assert.assertTrue(isSuccess,"支付交易处理失败");

        if(list == null) {
            Assert.assertTrue(false,"查找不到处理结果，requestId:"+payTestCase.getReq_result());
        }
    }
}
